# Структурный шаблон проектирования ("Компоновщик")
# Позволяет обращаться к отдельным объектам или группам объектов одинаково

import abc


class Item(metaclass=abc.ABCMeta):
    def __init__(self, name: str):
        self._item_name: str = name
        self._owner_name: str = None

    def set_owner(self, o: str):
        self._owner_name = o

    @abc.abstractmethod
    def add(self, sub_item: "Item"):
        pass

    @abc.abstractmethod
    def remove(self, sub_item: "Item"):
        pass

    @abc.abstractmethod
    def display(self):
        pass


class ClicableItem(Item):
    def __init__(self, name: str):
        super().__init__(name)

    def add(self, sub_item: Item):
        raise Exception("Кликабельный элемену нельзя добавить подэлемент")

    def remove(self, sub_item: Item):
        raise Exception("У кликабельного элемента не могут быть подэлементы")

    def display(self):
        print(self._owner_name + self._item_name)


class DropDownItem(Item):
    def __init__(self, name: str):
        super().__init__(name)
        self.__children = []

    def add(self, sub_item: Item):
        sub_item.set_owner(self._item_name)
        self.__children.append(sub_item)

    def remove(self, sub_item: Item):
        self.__children.remove(sub_item)

    def display(self):
        for item in self.__children:
            if self._owner_name is not None:
                print(self._owner_name, end="")
            item.display()


if __name__ == "__main__":
    file: Item = DropDownItem('файл->')

    create: Item = DropDownItem('Создать->')
    open_: Item = DropDownItem("Открыть->")
    exit_: Item = ClicableItem("Выход->")

    file.add(create)
    file.add(open_)
    file.add(exit_)

    project: Item = ClicableItem("Проект...")
    repository: Item = ClicableItem("Репозиторий...")

    create.add(project)
    create.add(repository)

    solution: Item = ClicableItem("Решение...")
    folder: Item = ClicableItem("Папка...")

    open_.add(solution)
    open_.add(folder)

    file.display()
    print()
    file.remove(create)
    file.display()

# файл->Создать->Проект...
# файл->Создать->Репозиторий...
# файл->Открыть->Решение...
# файл->Открыть->Папка...
# файл->Выход->

# файл->Открыть->Решение...
# файл->Открыть->Папка...
# файл->Выход->
